﻿
using System;
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Reflection;
using System.Windows.Forms;
using System.Runtime.InteropServices;
using System.Threading;


namespace Client
{
    public partial class MessageForm : Form
    {
        int thisHeightId = 0;

        public int HeightId
        {
            get { return thisHeightId; }
            set { thisHeightId = value; }
        }

        protected const Int32 HWND_TOPMOST = -1;
        protected const Int32 SWP_NOACTIVATE = 0x0010;

        // ShowWindow()
        protected const Int32 SW_SHOWNOACTIVATE = 4;
        [DllImport("user32.dll")]
        protected static extern bool ShowWindow(IntPtr hWnd, Int32 flags);
        [DllImport("user32.dll")]
        protected static extern bool SetWindowPos(IntPtr hWnd, Int32 hWndInsertAfter, Int32 X, Int32 Y, Int32 cx, Int32 cy, uint uFlags);

        [DllImport("user32.dll", CharSet = CharSet.Auto)]
        public static extern int SetWindowLong(IntPtr hWnd, int Index, int Value);

        delegate void setBoundCallBack(int inX, int inY, int width, int height);
        void setBound(int inX, int inY)
        {
            if (this.InvokeRequired)
            {
                setBoundCallBack d = new setBoundCallBack(SetBounds);
                this.Invoke(d, new object[] { inX, inY, this.Width, this.Height });
            }
            else
            {
                this.SetBounds(inX, inY, this.Width, this.Height);
            }
        }
        delegate void setWindowStateCallBack(FormWindowState inWindowState);
        void setWindowState(FormWindowState inWindowState)
        {
            if (this.InvokeRequired)
            {
                setWindowStateCallBack d = new setWindowStateCallBack(setWindowState);
                this.Invoke(d, new object[] { inWindowState });
            }
            else
            {
                this.WindowState = inWindowState;
            }
        }


        public MessageForm()
        {
            InitializeComponent();
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);
            SetStyle(ControlStyles.ContainerControl, false);
            SetStyle(ControlStyles.UserMouse, true);
            SetStyle(ControlStyles.UserPaint, true);
            SetStyle(ControlStyles.AllPaintingInWmPaint, true);		// WmPaint calls OnPaint and OnPaintBackground
            SetStyle(ControlStyles.DoubleBuffer, true);
            SetStyle(ControlStyles.Selectable, true);

            ShowInTaskbar = false;
            FormBorderStyle = System.Windows.Forms.FormBorderStyle.None;
            StartPosition = System.Windows.Forms.FormStartPosition.Manual;
        }

        Rectangle tmpRectangle;
        protected void viewTimer(object sender, System.EventArgs e)
        {
            viewClock.Stop();
            if (this.InvokeRequired)
            {
                this.Invoke(new Action(() => this.Close()));
            }
            else
                this.Close();
        }
        protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
        {
            if (keyData == Keys.Escape)
            {
                this.Close();
                return true;
            }
            return base.ProcessCmdKey(ref msg, keyData);
        }
        protected void show()
        {
            int thisTop = (this.Height + thisHeightId * 15)%Screen.PrimaryScreen.WorkingArea.Height;

            //滚动效果
            int tmp = 0;
            while (tmpRectangle.Bottom - this.Location.Y < thisTop)
            {
                if (tmp++ < 15)
                {
                    Thread.Sleep(1);
                    continue;
                }
                setBound(Left, Top - tmp);
                tmp = 0;
                Thread.Sleep(1);
            }
            if (tmp > 0)
                setBound(Left, Top - tmp);
        }

        public void ShowMessage(ShowMessageInfo inShowMessageInfo)
        {
            showMessageInfo = inShowMessageInfo;
            tmpRectangle = SystemInformation.WorkingArea;
            SetWindowLong(Handle, -20, 0x00000080);
            SetWindowPos(Handle, HWND_TOPMOST, tmpRectangle.Right - this.Width, tmpRectangle.Bottom, Width, Height, SWP_NOACTIVATE);
            ShowWindow(Handle, SW_SHOWNOACTIVATE);
            viewClock = new System.Windows.Forms.Timer();
            viewClock.Tick += new System.EventHandler(viewTimer);
            viewClock.Interval = 10000;
            viewClock.Start();
           Thread ShowThread = new Thread(new ThreadStart(show));
            ShowThread.IsBackground = true;
            ShowThread.Start();
        }

        int maxWidth;
        int maxHeight;
        int buttonCloseX;
        int buttonCloseY;
        System.Windows.Forms.Timer viewClock;

        ShowMessageInfo showMessageInfo;

        protected override void OnSizeChanged(EventArgs e)
        {
            base.OnSizeChanged(e);
            maxWidth = this.ClientSize.Width;//最大宽度
            maxHeight = this.ClientSize.Height;//最大高度
            buttonCloseX = maxWidth - 17;
            buttonCloseY = 5;
            Invalidate();
        }

        #region 绘制所有东西
        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;

            //外框，面板
            DrawPanel(e.Graphics);
            //水晶上
            DrawTitleUp(e.Graphics);
            //水晶下
            DrawTitleDown(e.Graphics);
            //标题框
            DrawTitleBorder(e.Graphics);


            //关闭按钮
            DrawButtonClose(e.Graphics);

            //showMessageInfo.messageType
            DrawTitleText(e.Graphics);
            //showMessageInfo.messageDateTime
            DrawDateTime(e.Graphics);
            //操作
            DrawOperator(e.Graphics);
            //text
            DrawOperateText(e.Graphics);
        }

        private void DrawPanel(Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            GraphicsPath gp = new GraphicsPath();
            gp.AddArc(0, 0, 6, 6, 180, 90);
            gp.AddArc(this.Width - 1 - 6, 0, 6, 6, 270, 90);
            gp.AddArc(this.Width - 1 - 6, this.Height - 1 - 6, 6, 6, 0, 90);
            gp.AddArc(0, this.Height - 1 - 6, 6, 6, 90, 90);
            gp.CloseFigure();
            Pen pen = new Pen(Color.FromArgb(237, 243, 243));
            Brush brush = pen.Brush;
            g.FillPath(brush, gp);
            Pen borderPen = new Pen(Color.FromArgb(70, 130, 180));
            g.DrawPath(borderPen, gp);

            pen.Dispose();
            brush.Dispose();
            borderPen.Dispose();
        }

        private void DrawTitleUp(Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            GraphicsPath gp = new GraphicsPath();
            gp.AddArc(0, 0, 6, 6, 180, 90);
            gp.AddArc(this.Width - 1 - 6, 0, 6, 6, 270, 90);
            gp.AddLine(this.Width - 1, 10, 0, 10);
            gp.CloseFigure();
            Color color1 = Color.FromArgb(240, 244, 243);
            Color color2 = Color.FromArgb(199, 217, 226);
            LinearGradientBrush lineBrush = new LinearGradientBrush(new Point(this.Width / 2, 0), new Point(this.Width / 2, 11), color1, color2);
            g.FillPath(lineBrush, gp);

            gp.Dispose();
            lineBrush.Dispose();
        }

        private void DrawTitleDown(Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            GraphicsPath gp = new GraphicsPath();
            gp.AddLine(0, 10, this.Width - 1, 10);
            gp.AddArc(this.Width - 1 - 6, 23 - 1 - 6, 6, 6, 0, 90);
            gp.AddArc(0, 23 - 1 - 6, 6, 6, 90, 90);
            gp.CloseFigure();
            Color color3 = Color.FromArgb(172, 199, 213);
            Color color4 = Color.FromArgb(240, 244, 243);
            LinearGradientBrush lineBrush = new LinearGradientBrush(new Point(this.Width / 2, 10), new Point(this.Width / 2, 23), color3, color4);
            g.FillPath(lineBrush, gp);

            gp.Dispose();
            lineBrush.Dispose();
        }

        private void DrawTitleBorder(Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            GraphicsPath gp = new GraphicsPath();
            gp.AddArc(0, 0, 6, 6, 180, 90);
            gp.AddArc(this.Width - 1 - 6, 0, 6, 6, 270, 90);
            gp.AddArc(this.Width - 1 - 6, 23 - 1 - 6, 6, 6, 0, 90);
            gp.AddArc(0, 23 - 1 - 6, 6, 6, 90, 90);
            gp.CloseFigure();
            Pen pen = new Pen(Color.FromArgb(70, 130, 180));
            g.DrawPath(pen, gp);

            gp.Dispose();
            pen.Dispose();
        }

        private void DrawButtonClose(Graphics g)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            GraphicsPath gp = new GraphicsPath();
            gp.AddLine(buttonCloseX, buttonCloseY, buttonCloseX + 1, buttonCloseY);                 //   -         -      -
            gp.AddLine(buttonCloseX + 1, buttonCloseY, buttonCloseX + 6, buttonCloseY + 5);         //   \        |  \  /  |
            gp.AddLine(buttonCloseX + 6, buttonCloseY + 5, buttonCloseX + 11, buttonCloseY);        //   /         \  \/  /
            gp.AddLine(buttonCloseX + 11, buttonCloseY, buttonCloseX + 12, buttonCloseY);           //   -         /  /\  \ 
            gp.AddLine(buttonCloseX + 12, buttonCloseY, buttonCloseX + 12, buttonCloseY + 1);       //   |        |  /  \  | 
            gp.AddLine(buttonCloseX + 12, buttonCloseY + 1, buttonCloseX + 7, buttonCloseY + 6);    //   /         -      - 
            gp.AddLine(buttonCloseX + 7, buttonCloseY + 6, buttonCloseX + 12, buttonCloseY + 11);   //   \          
            gp.AddLine(buttonCloseX + 12, buttonCloseY + 11, buttonCloseX + 12, buttonCloseY + 12); //   |        
            gp.AddLine(buttonCloseX + 12, buttonCloseY + 12, buttonCloseX + 11, buttonCloseY + 12); //   -         
            gp.AddLine(buttonCloseX + 11, buttonCloseY + 12, buttonCloseX + 6, buttonCloseY + 7);   //   \         
            gp.AddLine(buttonCloseX + 6, buttonCloseY + 7, buttonCloseX + 1, buttonCloseY + 12);    //  /         
            gp.AddLine(buttonCloseX + 1, buttonCloseY + 12, buttonCloseX, buttonCloseY + 12);       //  -        
            gp.AddLine(buttonCloseX, buttonCloseY + 12, buttonCloseX, buttonCloseY + 11);           //  |        
            gp.AddLine(buttonCloseX, buttonCloseY + 11, buttonCloseX + 5, buttonCloseY + 6);        //  /
            gp.AddLine(buttonCloseX + 5, buttonCloseY + 6, buttonCloseX, buttonCloseY + 1);         //   \
            gp.AddLine(buttonCloseX, buttonCloseY + 1, buttonCloseX, buttonCloseY);                 //   |

            gp.CloseFigure();
            Brush brush;
            brush = Brushes.SteelBlue;

            g.FillPath(brush, gp);

            gp.Dispose();
        }

        private void DrawTitleText(Graphics g)
        {
            Pen pen = new Pen(Color.FromArgb(11, 59, 99));
            Brush brush = pen.Brush;
            Pen pen1 = new Pen(Color.FromArgb(148, 181, 195));
            Brush brush1 = pen1.Brush;
            Font font = new Font("微软雅黑", 9);

            DrawText(g, showMessageInfo.messageType, font, brush1, brush, 10, 6);

            pen.Dispose();
            brush.Dispose();
            pen1.Dispose();
            brush1.Dispose();
            font.Dispose();
        }

        private void DrawDateTime(Graphics g)
        {
            Pen pen = new Pen(Color.FromArgb(11, 59, 99));
            Brush brush = pen.Brush;
            Pen pen1 = new Pen(Color.FromArgb(189, 219, 219));
            Brush brush1 = pen1.Brush;
            Font font = new Font("微软雅黑", 9);

            DrawText(g, "·" + showMessageInfo.messageDateTime, font, brush1, brush, 2, 23 + 5);

            pen.Dispose();
            brush.Dispose();
            pen1.Dispose();
            brush1.Dispose();
            font.Dispose();
        }

        private void DrawOperator(Graphics g)
        {
            Pen pen = new Pen(Color.FromArgb(11, 59, 99));
            Brush brush = pen.Brush;
            Pen pen1 = new Pen(Color.FromArgb(189, 219, 219));
            Brush brush1 = pen1.Brush;
            Font font = new Font("微软雅黑", 9);

            DrawText(g, "·" + showMessageInfo.messageTitle, font, brush1, brush, 2, 23 + 5 + 13 + 5);

            pen.Dispose();
            brush.Dispose();
            pen1.Dispose();
            brush1.Dispose();
            font.Dispose();
        }

        private void DrawOperateText(Graphics g)
        {
            Pen pen = new Pen(Color.FromArgb(11, 59, 99));
            Brush brush = pen.Brush;
            Pen pen1 = new Pen(Color.FromArgb(189, 219, 219));
            Brush brush1 = pen1.Brush;
            Font font = new Font("微软雅黑", 9);

            DrawText(g, "    " + showMessageInfo.messageValue, font, brush1, brush, 14, 23 + 5 + 13 + 5 + 13 + 2, this.Width - 14 - 7, this.Height - (23 + 5 + 13 + 5 + 13 + 2) - 22);

            pen.Dispose();
            brush.Dispose();
            pen1.Dispose();
            brush1.Dispose();
            font.Dispose();
        }

        private void DrawText(Graphics g, string text, Font font, Brush brush1, Brush brush, int left, int top)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            g.DrawString(text, font, brush1, left - 1, top - 1);
            g.DrawString(text, font, brush1, left, top - 1);
            g.DrawString(text, font, brush1, left + 1, top - 1);
            g.DrawString(text, font, brush1, left + 1, top);
            g.DrawString(text, font, brush1, left + 1, top + 1);
            g.DrawString(text, font, brush1, left, top + 1);
            g.DrawString(text, font, brush1, left - 1, top + 1);
            g.DrawString(text, font, brush1, left - 1, top);
            g.DrawString(text, font, brush, left, top);
        }

        private void DrawText(Graphics g, string text, Font font, Brush brush1, Brush brush, int left, int top, int width, int height)
        {
            g.SmoothingMode = SmoothingMode.AntiAlias;

            g.DrawString(text, font, brush1, new RectangleF(left - 1, top - 1, width + 1, height + 1));
            g.DrawString(text, font, brush1, new RectangleF(left, top - 1, width, height + 1));
            g.DrawString(text, font, brush1, new RectangleF(left + 1, top - 1, width - 1, height + 1));
            g.DrawString(text, font, brush1, new RectangleF(left + 1, top, width - 1, height));
            g.DrawString(text, font, brush1, new RectangleF(left + 1, top + 1, width - 1, height - 1));
            g.DrawString(text, font, brush1, new RectangleF(left, top + 1, width, height - 1));
            g.DrawString(text, font, brush1, new RectangleF(left - 1, top + 1, width + 1, height - 1));
            g.DrawString(text, font, brush1, new RectangleF(left - 1, top, width + 1, height));
            g.DrawString(text, font, brush, new RectangleF(left, top, width, height));
        }
        #endregion

        private void Form1_MouseUp(object sender, MouseEventArgs e)
        {
            if (e.X > buttonCloseX && e.Y < buttonCloseY + 12)
                this.Close();
         
        }
        protected override void OnDoubleClick(EventArgs e)
        {
            this.Close();
            this.showMessageInfo.MessageProcess();
        }
        protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
        {
            base.OnClosing(e);
        }
    }
}